package com.aluka.furme.lm.service.common;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.aluka.furme.lm.entity.BaseEntity;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

public abstract class BaseService<T extends BaseEntity> extends AbstractCommonService {

    private String fileName;

    private Class<T> typeArgument;

    public BaseService(String fileName) {
        this.fileName = fileName;
        this.typeArgument = (Class<T>) ClassUtil.getTypeArgument(this.getClass());
    }

    /**
     * 获取所有数据
     *
     * @return list
     */
    public List<T> list() {
        return list(typeArgument);
    }

    public List<T> list(Class<T> cls) {
        JSONObject jsonObject = getJSONObject();
        if (jsonObject == null) {
            return new ArrayList<>();
        }
        JSONArray jsonArray = formatToArray(jsonObject);
        return jsonArray.toList(cls);
    }

    public JSONObject getJSONObject() {
        Objects.requireNonNull(fileName, "没有配置fileName");
        return getJSONObject(fileName);
    }

    /**
     * 工具id 获取 实体
     *
     * @param id 数据id
     * @return T
     */
    public T getItem(String id) {
        Objects.requireNonNull(fileName, "没有配置fileName");
        return getJsonObjectById(fileName, id, typeArgument);
    }


    /**
     * 添加实体
     *
     * @param t 实体
     */
    public void addItem(T t) {
        save(fileName, t);
    }

    /**
     * 删除实体
     *
     * @param id 数据id
     */
    public void deleteItem(String id) {
        if(id.contains(",")){
            for (String s : StringUtils.split(id, ",")) {
                delete(fileName, s);
            }
        }else{
            delete(fileName, id);
        }
    }

    /**
     * 修改实体
     *
     * @param t 实体
     */
    public void updateItem(T t) {

        update(fileName, t);
    }

    /**
     * 修改实体
     *
     * @param t 实体
     * @param notAll 修改有值的内容
     */
    public void updateItem(T t,boolean notAll,String... ignores) {
        if(notAll){
            T item = getItem(t.getId());
            List<String> ignoreNames = ignores != null ? Lists.newArrayList(ignores):Lists.newArrayList();
            for (Field field : t.getClass().getDeclaredFields()) {
                Object fieldValue = ReflectUtil.getFieldValue(t, field.getName());
                if(null != fieldValue && !ignoreNames.contains(field.getName())){
                    ReflectUtil.setFieldValue(item,field.getName(),fieldValue);
                }
            }
            updateItem(item);
        }else{
            update(fileName, t);
        }
    }

    private JSONArray formatToArray(JSONObject jsonObject) {
        if (jsonObject == null) {
            return new JSONArray();
        }
        Set<String> setKey = jsonObject.keySet();
        JSONArray jsonArray = new JSONArray();
        for (String key : setKey) {
            jsonArray.add(jsonObject.getJSONObject(key));
        }
        return jsonArray;
    }
}
